package net.onceface.application.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Named;

import net.onceface.application.AddressApplication;
import net.onceface.application.OrderApplication;
import net.onceface.application.assembler.OrderAssembler;
import net.onceface.application.assembler.OrderProductAssembler;
import net.onceface.application.commons.InvokeResult;
import net.onceface.application.commons.Message;
import net.onceface.application.dto.CartDTO;
import net.onceface.application.dto.DisCountDTO;
import net.onceface.application.dto.OrderDTO;
import net.onceface.core.domain.Order;
import net.onceface.core.domain.OrderProduct;
import net.onceface.core.domain.Product;
import net.onceface.core.domain.Spec;
import net.onceface.core.domain.enums.NumberType;
import net.onceface.core.domain.enums.OrderStatus;
import net.onceface.core.domain.enums.Payment;
import net.onceface.core.domain.mappedsuper.CreateNumber;
import net.onceface.infra.querychannel.QueryChannelService;
import net.onceface.infra.spring.ioc.InstanceFactory;

import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;
@Named
@Transactional
public class OrderApplicationImpl implements OrderApplication{
	
	@Inject
	private AddressApplication addressApplication;
	
	Logger logger  =  Logger.getLogger(OrderApplicationImpl.class );

	private QueryChannelService queryChannel;
	
	private QueryChannelService getQueryChannelService() {
		if (queryChannel == null) {
			queryChannel = InstanceFactory.getInstance(
					QueryChannelService.class, "queryChannel");
		}
		return queryChannel;
	}
	
	@SuppressWarnings({ "unchecked" })
	@Override
	public OrderDTO orderAnalysis(Long clientId, Long disCountId) {
		//用户的购物车
		List<CartDTO> cartDTOs = CartApplicationImpl.getCartByClientId(clientId);
		if(cartDTOs != null){
			//计算订单信息（获取可用优惠列表）
			Map<String, Object> cartDetails = CartApplicationImpl.countCart(cartDTOs, null);
			List<OrderProduct> orderProducts = new ArrayList<OrderProduct>();
			OrderDTO orderDTO = new OrderDTO(clientId, OrderStatus.Z);
			for(CartDTO cartDTO : cartDTOs){
				if(cartDTO.isChecked() && cartDTO.isValid()){
					OrderProduct orderProduct = new OrderProduct(cartDTO.getProductId(), 
							cartDTO.getProductPicture(), cartDTO.getProductPrice(),
							cartDTO.getProductName(), cartDTO.getSpecName());
					orderProduct.setQuantity(cartDTO.getQuantity());	
					if(cartDTO.getSpecID() != null && cartDTO.getSpecID() >0){
						orderProduct.setSpecId(cartDTO.getSpecID());
					}
					orderProducts.add(orderProduct);
				}
			}
			if(disCountId != null && disCountId > 0){
				//如果有传入优惠ID则重新计算价钱
				Set<DisCountDTO> disCountDTOs = (Set<DisCountDTO>) cartDetails.get("disCounts");
				if(disCountDTOs.size() > 0){
					int b = 0;
					for(DisCountDTO disCountDTO : disCountDTOs){
						b++;
						if(disCountDTO.getId() == disCountId){
							//有找到传入的优惠ID，重新计算价格
							cartDetails = CartApplicationImpl.countCart(cartDTOs, disCountId);
							orderDTO.setTotalPrice((double)cartDetails.get("totalPrice"));
							orderDTO.setPrice((double)cartDetails.get("price"));
							orderDTO.setDiscount((double)cartDetails.get("disCountPrice"));
							orderDTO.setDisCountId(disCountDTO.getId());
							break;
						}
						if(b == disCountDTOs.size()){
							//有传优惠ID，但又没找到这个ID的优惠
							return null;
						}
					}
				}else{
					//有传优惠ID，但又没找到可用的优惠
					return null;
				}			
			}else{
				//没使用优惠或使用默认优惠，直接取原价
				orderDTO.setTotalPrice((double)cartDetails.get("totalPrice"));
				orderDTO.setPrice((double)cartDetails.get("price"));
				orderDTO.setDiscount((double)cartDetails.get("disCountPrice"));
			}
			if(orderProducts.size() > 0){
				//订单有商品设置订单分析信息，存入数据库
				orderDTO.setOrderProducts(OrderProductAssembler.toDTOs(orderProducts));
				OrderAssembler.toEntity(orderDTO).save();
				//查找用户所有收货地址
				orderDTO.setAddresses(addressApplication.findByClientId(clientId));
				return orderDTO;
			}else{
				//订单没商品
				return null;
			}
		}else{
			//购物车没有合法商品
			return null;
		}
	}

	@Override
	public InvokeResult placeOrder(OrderDTO orderDTO) {
		Order order = Order.getOrderByOrderNumber(orderDTO.getOrderNumber());
		if(order == null){
			return InvokeResult.failure(Message.ORDER_IS_NULL);
		}
		//检查商品库存
		for(OrderProduct orderProduct : order.getOrderProducts()){
			if(orderProduct.getSpecId() != null && orderProduct.getSpecId() > 0){
				Spec spec = Spec.get(Spec.class, orderProduct.getSpecId());
				if(orderProduct.getQuantity() > spec.getStock()){
					return InvokeResult.failure("商品：" + orderProduct.getName() + 
						Message.GET_STOCK_MESSAGE + spec.getStock() + "了！");
				}
			}else{
				Product product = Product.get(Product.class, orderProduct.getProductId());
				if(orderProduct.getQuantity() > product.getStock()){
					return InvokeResult.failure("商品：" + orderProduct.getName() + 
							Message.GET_STOCK_MESSAGE + product.getStock() + "了！");
				}
			}
		}
		//是否使用了优惠券
		if(orderDTO.getCouponsId() != null){
			
		}
		//订单改为未付款
		order.setOrderStatus(OrderStatus.A);
		//设置收货人
		order.setAddress(orderDTO.getAddress());
		order.setPhone(orderDTO.getPhone());
		order.setReceiver(orderDTO.getReceiver());
		//设置支付方式
		if(orderDTO.getPayment() == Payment.Offline){
			order.setOrderStatus(OrderStatus.B);
		}
		order.setPayment(orderDTO.getPayment());
		//分配订单编号
		order.setOrderNumber(CreateNumber.createNumber(NumberType.A));
		order.save();
		return InvokeResult.success(order.getOrderNumber());
	}

	@Override
	public OrderDTO getOrderByNumber(String orderNumber) {
		return OrderAssembler.toDTO(Order.getOrderByOrderNumber(orderNumber), false);
	}

	@Override
	public InvokeResult editStatus(Long id, String orderNumber, OrderStatus orderStatus) {
		Order order = null;
		if(id != null && id > 0){
			order = Order.get(Order.class, id);
		}
		if(orderNumber != null){
			order = Order.getOrderByOrderNumber(orderNumber);
		}
		if(order == null){
			return InvokeResult.failure("没有该订单信息!");
		}
		order.setOrderStatus(orderStatus);
		order.save();
		logger.info("订单编号：" + order.getOrderNumber() + " 的状态改为" + orderStatus);
		return InvokeResult.success();
	}

	@Override
	public InvokeResult update(Order order) {
		order.save();
		return InvokeResult.success();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<OrderDTO> findOrderByClient(Long clientId, String status) {
		StringBuilder jpql = new StringBuilder("SELECT new net.onceface.application.dto.OrderDTO(_order.id,_order.orderNumber,_order.price,_order.clientId,_order.orderStatus,_order.createDate) FROM Order _order WHERE _order.orderStatus <> 'Z'");
		jpql.append(" AND _order.clientId = :clientId");
		if(status != null){
			jpql.append(" AND _order.orderStatus = '" + status + "'");
		}
		List<OrderDTO> orders = getQueryChannelService().createJpqlQuery(jpql.toString())
				.addParameter("clientId", clientId).list();
		for(OrderDTO order : orders){
			List<OrderProduct> products = new ArrayList<OrderProduct>();
			products.addAll(OrderProduct.findByOrderId(order.getId()));
			order.setOrderProducts(OrderProductAssembler.toDTOs(products));
		}
		return orders;
	}

	@Override
	public InvokeResult cancelOrder(Long clientId, Long Id) {
		Order order = Order.get(Order.class, Id);
		if(order.getClientId() != clientId || order.getOrderStatus() == OrderStatus.Z){
			return InvokeResult.failure(Message.ILLEGAL_OPERATION);
		}
		if(order.getOrderStatus() != OrderStatus.A || order.getOrderStatus() != OrderStatus.B){
			return InvokeResult.failure("这个状态不能取消订单了！");
		}
		order.setOrderStatus(OrderStatus.E);
		order.save();
		return InvokeResult.success();
	}

	@Override
	public OrderDTO getDetailByOrderNumber(String orderNumber) {
		return OrderAssembler.toDTO(Order.getOrderByOrderNumber(orderNumber), true);
	}
}
